package com.aiti.ai.service.impl;


import com.aiti.ai.dto.ai.GenerateEnterpriseDieldDto;
import com.aiti.ai.entity.*;
import com.aiti.ai.mapper.ShowPremuEnterpriseMapper;

import com.aiti.ai.service.ShowPremuEnterpriseService;
import com.aiti.ai.service.ai.MessageAssistant;


import com.aiti.ai.tool.SearXNGWebSearchTool;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.service.AiServices;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 
 * @since 2025-03-22
 */
@Service
@Slf4j
public class ShowPremuEnterpriseServiceImpl extends ServiceImpl<ShowPremuEnterpriseMapper, ShowPremuEnterpriseEntity> implements ShowPremuEnterpriseService {

    @Autowired
    private ChatLanguageModel model;

    @Autowired
    private SearXNGWebSearchTool searXNGWebSearchTool;

    @Autowired
    private ThreadPoolExecutor executorService;


    private final AtomicLong taskCounter = new AtomicLong(0);
    private final Object lock = new Object();
    private volatile boolean shutdownRequested = false;

    @Override
    public void dealEnterprise(String id) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        LambdaQueryWrapper<ShowPremuEnterpriseEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShowPremuEnterpriseEntity::getDealFlag, 0);
        if(!StringUtils.isEmpty(id)){
            queryWrapper.eq(ShowPremuEnterpriseEntity::getId, id);
        }

        int pageSize = 100;
        int currentPage = 1;
        boolean hasMore = true;
        //while (!shutdownRequested && hasMore) {
            Page<ShowPremuEnterpriseEntity> pageResult = this.page(new Page<>(currentPage, pageSize), queryWrapper);
            List<ShowPremuEnterpriseEntity> enterpriseList = pageResult.getRecords();

//            if (enterpriseList.isEmpty()) {
//                hasMore = false;
//                break;
//            }

            for (final ShowPremuEnterpriseEntity enterpriseEntity : enterpriseList) {
                if (shutdownRequested) {
                    break;
                }
                // 提交任务给线程池
                executorService.submit(() -> {
                    try {
                        processEnterpriseEntity(enterpriseEntity, formatter);
                    } catch (Exception e) {
                        log.error(e.getMessage());
                    } finally {
                        taskCounter.decrementAndGet();
                        synchronized (lock) {
                            lock.notifyAll();
                        }
                    }
                });
                taskCounter.incrementAndGet();
            }

            if (enterpriseList.size() < pageSize) {
                hasMore = false;
            }

            currentPage++;
        //}


        synchronized (lock) {
            while (taskCounter.get() > 0 && !shutdownRequested) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }


        if (shutdownRequested) {
            shutdownExecutorService();
        }
    }

    @Override
    public void requestShutdown() {
        this.shutdownRequested = true;
        synchronized (lock) {
            lock.notifyAll();
        }
    }

    private void shutdownExecutorService() {
        executorService.shutdown();
        try {
            if (!executorService.awaitTermination(1, TimeUnit.HOURS)) {
                executorService.shutdownNow();
            }

        } catch (InterruptedException ie) {
            Thread.currentThread().interrupt();
        }
    }

    private void processEnterpriseEntity(ShowPremuEnterpriseEntity enterpriseEntity, SimpleDateFormat formatter) throws Exception {
        String baseName = enterpriseEntity.getCompanyName();
        
        MessageAssistant assistant = AiServices.builder(MessageAssistant.class)
                .chatLanguageModel(model)
                .tools(searXNGWebSearchTool).build();
        GenerateEnterpriseDieldDto fieldDto = assistant.generateEnterpriseField(baseName);
        log.info("ai生成字段返回结果:{}",fieldDto);
        ShowPremuEnterpriseEntity showPremuEnterpriseEntity = new ShowPremuEnterpriseEntity();
        BeanUtils.copyProperties(fieldDto, showPremuEnterpriseEntity);

        Class<? extends ShowPremuEnterpriseEntity> aClass = populateValue(enterpriseEntity, showPremuEnterpriseEntity, null, true);


        enterpriseEntity.setDealFlag(1);
        
        this.saveOrUpdate(enterpriseEntity);
        
    }



    
    

    private static Class<? extends ShowPremuEnterpriseEntity> populateValue(ShowPremuEnterpriseEntity destEntity, ShowPremuEnterpriseEntity sourceEntity, Class<? extends ShowPremuEnterpriseEntity> destClass,boolean dealOldFieldFlag) throws IllegalAccessException, NoSuchFieldException {
        Class<?> clazz = sourceEntity.getClass();

        Class<? extends ShowPremuEnterpriseEntity> aClass = destClass == null ? destEntity.getClass() : destClass;
        // 获取对象的字段
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            field.setAccessible(true); // 设置为可访问私有字段
            String fieldName = field.getName();
            Object fieldValue = field.get(sourceEntity);
            if("serialVersionUID".equals(fieldName)){
                continue;
            }
            if (fieldValue != null) {
                Field field1 = aClass.getDeclaredField(fieldName);
                field1.setAccessible(true);
                Object oldFieldValue = field1.get(destEntity);
                if(dealOldFieldFlag){
                    if(oldFieldValue == null || "".equals(oldFieldValue)){
                        field1.set(destEntity, fieldValue);
                    }
                }else{
                    field1.set(destEntity, fieldValue);
                }

            }
        }
        return aClass;
    }

    @Override
    public List<ShowPremuEnterpriseEntity> pageQuery(int limit, int offset) {
        return this.baseMapper.pageQuery(limit, offset);
    }

    @Override
    public int queryUnDealCount() {
        return this.baseMapper.queryUnDealCount();
    }
}
